Skip to content

refactor: replace js_sys calls with proper Rust crates, extract CSS design tokens#40

Merged
gfauredev merged 8 commits intomainfrom
copilot/add-replay-button-done-exercises
Feb 27, 2026
Merged

refactor: replace js_sys calls with proper Rust crates, extract CSS design tokens#40
gfauredev merged 8 commits intomainfrom
copilot/add-replay-button-done-exercises

Conversation

Copy link
Contributor

Copilot AI commented Feb 26, 2026

Replace js_sys::Date::now() and dioxus::document::eval() with idiomatic Rust equivalents. Extract hardcoded CSS colors/values into :root custom properties.

js_sys → proper Rust crate functions

  • js_sys::Date::now()time::OffsetDateTime::now_utc() across 4 call sites (models/mod.rs, services/exercise_db.rs ×2, components/analytics.rs). Removes platform cfg branching since the time crate (already a dep with wasm-bindgen feature) handles both targets:
// Before (cfg-branched)
#[cfg(target_arch = "wasm32")]
{ (js_sys::Date::now() / 1000.0) as u64 }
#[cfg(not(target_arch = "wasm32"))]
{ SystemTime::now().duration_since(UNIX_EPOCH).unwrap_or_default().as_secs() }

// After (unified)
time::OffsetDateTime::now_utc().unix_timestamp() as u64
  • dioxus::document::eval() → web-sys event listener in exercise_list.rs: replaces inline JS string with wasm_bindgen::Closure + Reflect::set on window.onscroll
  • js_sys::Arrayserde_wasm_bindgen::to_value for notification vibrate pattern in session_timers.rs
  • Added "Element" to web-sys features for scroll position APIs

Remaining js_sys usage is only in wake_lock.rs (Wake Lock API has no typed web-sys bindings) and the Reflect::set for window.onscroll assignment.

CSS :root design tokens

Added :root block with ~25 custom properties covering colors, gradients, surfaces, borders, text, and border-radius. Replaced 150+ hardcoded values with var() references. One-off dark tints and rgba() shadows left as literals.

.analytics-panel class fix

Renamed CSS class from .analytics to .analytics-panel to match e2e test selectors (2 failing tests).

Verification

121 unit tests, 31 e2e tests, clippy clean.


💡 You can make Copilot smarter by setting up custom instructions, customizing its development environment and configuring Model Context Protocol (MCP) servers. Learn more Copilot coding agent tips in the docs.

Copilot AI and others added 2 commits February 26, 2026 19:38
…CD filter

Co-authored-by: gfauredev <19304085+gfauredev@users.noreply.github.com>
Co-authored-by: gfauredev <19304085+gfauredev@users.noreply.github.com>
Copilot AI changed the title [WIP] Add replay button on completed exercises for quick access feat: replay button, notification fixes, clickable exercise tags, toast auto-dismiss, CD commit filter Feb 26, 2026
@github-actions
Copy link

github-actions bot commented Feb 26, 2026

🧪 Unit Tests & Coverage

Test Results

info: cargo-llvm-cov currently setting cfg(coverage); you can opt-out it by passing --no-cfg-coverage
�[1m�[92m    Updating�[0m crates.io index
�[1m�[92m   Compiling�[0m log-workout v0.1.0 (/home/runner/work/LogOut/LogOut)
�[1m�[92m    Finished�[0m `test` profile [unoptimized + debuginfo] target(s) in 12.29s
�[1m�[92m     Running�[0m unittests src/main.rs (target/llvm-cov-target/debug/deps/log_workout-ab1956251af3abe0)

running 121 tests
test models::tests::all_forces_serde_round_trip ... ok
test models::tests::all_categories_serde_round_trip ... ok
test models::tests::all_equipment_serde_round_trip ... ok
test models::tests::all_muscles_serde_round_trip ... ok
test models::tests::category_all_contains_every_variant ... ok
test models::tests::category_display_all_variants ... ok
test models::tests::category_round_trip ... ok
test models::tests::distance_display_fractional_km ... ok
test models::tests::distance_display_metres ... ok
test models::tests::distance_display_whole_km ... ok
test models::tests::equipment_all_contains_every_variant ... ok
test models::tests::equipment_display_all_variants ... ok
test models::tests::equipment_round_trip ... ok
test models::tests::exercise_get_first_image_url_none ... ok
test models::tests::exercise_backward_compat_missing_optional_fields ... ok
test models::tests::exercise_full_json_deserialization ... ok
test models::tests::exercise_get_first_image_url_some ... ok
test models::tests::exercise_get_image_url_by_index ... ok
test models::tests::exercise_get_image_url_full_url_passthrough ... ok
test models::tests::exercise_level_none_when_missing_from_json ... ok
test models::tests::exercise_level_some_when_present_in_json ... ok
test models::tests::exercise_log_duration_saturates_on_underflow ... ok
test models::tests::exercise_log_duration_seconds ... ok
test models::tests::exercise_log_duration_seconds_none_when_incomplete ... ok
test models::tests::exercise_log_force_none_is_omitted_in_json ... ok
test models::tests::exercise_log_is_complete ... ok
test models::tests::exercise_log_serde_round_trip_with_all_fields ... ok
test models::tests::exercise_minimal ... ok
test models::tests::exercise_optional_fields_none ... ok
test models::tests::find_active_session_returns_first_without_end_time ... ok
test models::tests::find_active_session_returns_none_for_empty_list ... ok
test models::tests::finish_session_cancelled_session_is_not_stored ... ok
test models::tests::find_active_session_returns_none_when_all_finished ... ok
test models::tests::force_all_contains_every_variant ... ok
test models::tests::finish_session_with_exercises_is_stored ... ok
test models::tests::force_display_all_variants ... ok
test models::tests::force_has_reps ... ok
test models::tests::format_time_boundary_values ... ok
test models::tests::format_time_hours ... ok
test models::tests::format_time_minutes_seconds ... ok
test models::tests::get_current_timestamp_returns_reasonable_value ... ok
test models::tests::level_display_all_variants ... ok
test models::tests::level_serde_round_trip ... ok
test models::tests::mechanic_display_all_variants ... ok
test models::tests::mechanic_serde_round_trip ... ok
test models::tests::muscle_display_all_variants ... ok
test models::tests::muscle_all_contains_every_variant ... ok
test models::tests::muscle_round_trip ... ok
test models::tests::parse_distance_km_invalid ... ok
test models::tests::parse_distance_km_large_value_clamped ... ok
test models::tests::parse_distance_km_nan_and_infinity ... ok
test models::tests::parse_distance_km_valid ... ok
test models::tests::parse_weight_kg_invalid ... ok
test models::tests::parse_weight_kg_large_value_clamped ... ok
test models::tests::parse_weight_kg_nan_and_infinity ... ok
test models::tests::parse_weight_kg_valid ... ok
test models::tests::pending_ids_include_repeated_exercises ... ok
test models::tests::remove_first_occurrence_from_pending_ids ... ok
test models::tests::session_with_only_pending_exercises_is_cancelled ... ok
test models::tests::weight_display_fractional_kg ... ok
test models::tests::user_exercise_serialization_with_all_fields ... ok
test models::tests::weight_display_whole_kg ... ok
test models::tests::weight_display_zero ... ok
test models::tests::workout_exercise_serde_round_trip ... ok
test models::tests::workout_serde_round_trip ... ok
test models::tests::workout_session_backward_compat_missing_pending_ids ... ok
test models::tests::workout_session_current_exercise_fields_default_none ... ok
test models::tests::workout_session_is_active ... ok
test models::tests::workout_session_is_cancelled_when_no_exercises ... ok
test models::tests::workout_session_is_not_cancelled_when_has_exercises ... ok
test models::tests::workout_session_new_has_empty_pending_ids ... ok
test models::tests::workout_session_new_has_no_end_time ... ok
test models::tests::workout_session_pending_ids_serialization_round_trip ... ok
test models::tests::workout_session_with_exercise_logs_serde ... ok
test models::tests::workout_set_without_optionals ... ok
test models::tests::workout_set_serde_round_trip ... ok
test services::exercise_db::tests::get_equipment_types_deduplicates ... ok
test services::exercise_db::tests::get_exercise_by_id_found ... ok
test services::exercise_db::tests::exercises_json_url_uses_fork ... ok
test services::exercise_db::tests::get_equipment_types_only_returns_some_equipment ... ok
test services::exercise_db::tests::get_exercise_by_id_not_found ... ok
test services::exercise_db::tests::get_muscle_groups_deduplicates ... ok
test services::exercise_db::tests::get_muscle_groups_only_returns_primary_muscles ... ok
test services::exercise_db::tests::is_refresh_due_false_at_exact_interval_boundary ... ok
test services::exercise_db::tests::is_refresh_due_false_when_recent ... ok
test services::exercise_db::tests::is_refresh_due_true_when_no_timestamp ... ok
test services::exercise_db::tests::is_refresh_due_true_when_stale ... ok
test services::exercise_db::tests::native::clear_fetch_cache_removes_config_value ... ok
test services::exercise_db::tests::native::download_exercises_returns_empty_vec_on_200_empty_json ... ok
test services::exercise_db::tests::native::download_exercises_returns_error_on_connection_refused ... ok
test services::exercise_db::tests::native::download_exercises_returns_error_on_http_404 ... ok
test services::exercise_db::tests::native::is_refresh_due_false_after_fresh_timestamp ... ok
test services::exercise_db::tests::native::is_refresh_due_true_when_no_config_entry ... ok
test services::exercise_db::tests::search_by_category ... ok
test services::exercise_db::tests::search_by_equipment ... ok
test services::exercise_db::tests::search_by_force ... ok
test services::exercise_db::tests::search_by_level ... ok
test services::exercise_db::tests::search_by_muscle ... ok
test services::exercise_db::tests::search_by_name ... ok
test services::exercise_db::tests::search_by_secondary_muscle ... ok
test services::exercise_db::tests::search_by_secondary_muscle_biceps ... ok
test services::exercise_db::tests::native::record_fetch_timestamp_writes_numeric_value ... ok
test services::exercise_db::tests::search_case_insensitive ... ok
test services::exercise_db::tests::search_custom_exercise_by_category_unified ... ok
test services::exercise_db::tests::search_custom_exercise_by_muscle_unified ... ok
test services::exercise_db::tests::search_custom_exercise_by_secondary_muscle_unified ... ok
test services::exercise_db::tests::search_empty_query_returns_all ... ok
test services::exercise_db::tests::search_no_match ... ok
test services::exercise_db::tests::search_with_none_equipment_does_not_match_equipment_query ... ok
test services::exercise_db::tests::search_with_none_force_does_not_match_force_query ... ok
test services::service_worker::tests::register_service_worker_noop_on_native ... ok
test services::wake_lock::tests::enable_wake_lock_noop_on_native ... ok
test utils::tests::exercise_db_url_storage_key_is_stable ... ok
test utils::tests::days_since_uses_local_midnight_boundary ... ok
test utils::tests::format_session_date_beginning_of_today ... ok
test utils::tests::format_session_date_days_ago ... ok
test utils::tests::format_session_date_end_of_yesterday ... ok
test utils::tests::format_session_date_today ... ok
test utils::tests::format_session_date_two_days_ago ... ok
test utils::tests::format_session_date_yesterday ... ok
test utils::tests::get_exercise_db_url_returns_default_on_native ... ok

test result: ok. 121 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.15s

Coverage Summary

Filename                                 Regions    Missed Regions     Cover   Functions  Missed Functions  Executed       Lines      Missed Lines     Cover    Branches   Missed Branches     Cover
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
components/active_session.rs                 397               397     0.00%          31                31     0.00%         217               217     0.00%           0                 0         -
components/add_custom_exercise.rs             30                30     0.00%           3                 3     0.00%          24                24     0.00%           0                 0         -
components/analytics.rs                      181               181     0.00%          32                32     0.00%         108               108     0.00%           0                 0         -
components/bottom_nav.rs                       1                 1     0.00%           1                 1     0.00%           1                 1     0.00%           0                 0         -
components/completed_exercise_log.rs          95                95     0.00%          14                14     0.00%          48                48     0.00%           0                 0         -
components/credits.rs                         18                18     0.00%           3                 3     0.00%          16                16     0.00%           0                 0         -
components/edit_custom_exercise.rs            47                47     0.00%          12                12     0.00%          32                32     0.00%           0                 0         -
components/exercise_card.rs                   44                44     0.00%           4                 4     0.00%          31                31     0.00%           0                 0         -
components/exercise_form_fields.rs           190               190     0.00%          24                24     0.00%         104               104     0.00%           0                 0         -
components/exercise_list.rs                  152               152     0.00%          12                12     0.00%          84                84     0.00%           0                 0         -
components/home.rs                            76                76     0.00%          19                19     0.00%          45                45     0.00%           0                 0         -
components/session_exercise_form.rs           28                28     0.00%          15                15     0.00%          15                15     0.00%           0                 0         -
components/session_timers.rs                  27                27     0.00%          11                11     0.00%          17                17     0.00%           0                 0         -
components/workout_log.rs                     96                96     0.00%          14                14     0.00%          60                60     0.00%           0                 0         -
main.rs                                       50                50     0.00%          16                16     0.00%          35                35     0.00%           0                 0         -
models/mod.rs                               1504                 3    99.80%         109                 1    99.08%        1025                 2    99.80%           0                 0         -
services/exercise_db.rs                      711                 4    99.44%          66                 2    96.97%         440                 2    99.55%           0                 0         -
services/exercise_loader.rs                   56                56     0.00%           6                 6     0.00%          36                36     0.00%           0                 0         -
services/service_worker.rs                     6                 0   100.00%           2                 0   100.00%           6                 0   100.00%           0                 0         -
services/storage.rs                          365               298    18.36%          55                43    21.82%         223               176    21.08%           0                 0         -
services/wake_lock.rs                          5                 0   100.00%           2                 0   100.00%           5                 0   100.00%           0                 0         -
utils.rs                                     117                 1    99.15%          13                 0   100.00%          67                 1    98.51%           0                 0         -
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
TOTAL                                       4196              1794    57.24%         464               263    43.32%        2639              1054    60.06%           0                 0         -

Coverage Gate ✅ PASSED — all tested files have ≥ 90% coverage

File Lines Hit/Total Coverage Status
src/models/mod.rs 1023/1025 99%
src/services/exercise_db.rs 438/440 99%
src/services/service_worker.rs 6/6 100%
src/services/wake_lock.rs 5/5 100%
src/utils.rs 66/67 98%

@github-actions
Copy link

📸 E2E Test Failures

test-failed-1
test-failed-1
test-failed-1
test-failed-1

Co-authored-by: gfauredev <19304085+gfauredev@users.noreply.github.com>
Copilot AI changed the title feat: replay button, notification fixes, clickable exercise tags, toast auto-dismiss, CD commit filter fix: rename analytics CSS class to match e2e test selectors Feb 27, 2026
Copilot AI and others added 3 commits February 27, 2026 10:52
… eval with web-sys scroll listener, use serde_wasm_bindgen for vibrate array

Co-authored-by: gfauredev <19304085+gfauredev@users.noreply.github.com>
Replace all hardcoded color, gradient, border-radius, and surface
values throughout styles.css with var() references to the design
tokens defined in the :root block. One-off dark tints, rgba shadows,
and the :root definitions themselves are intentionally left unchanged.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…into :root CSS custom properties

Co-authored-by: gfauredev <19304085+gfauredev@users.noreply.github.com>
Copilot AI changed the title fix: rename analytics CSS class to match e2e test selectors refactor: replace js_sys calls with proper Rust crates, extract CSS design tokens Feb 27, 2026
@gfauredev gfauredev marked this pull request as ready for review February 27, 2026 11:13
@gfauredev gfauredev merged commit 2635657 into main Feb 27, 2026
4 of 5 checks passed
@gfauredev gfauredev deleted the copilot/add-replay-button-done-exercises branch February 27, 2026 11:24
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants